package com.kaluli.project.service;


import java.util.Collection;

import javax.annotation.Resource;

import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.serializer.SerializerFeature;


/**
 * 
 * @author niwei
 * @since 2015年11月24日
 * @version 1.0.0
 */
@Component
public class MemoryCache<T> {
	
	@Resource
	private RedisTemplate<String, T> redisTemplate;

	
	/**
	 * 向redis存入数据，并设置过期时间。
	 * @author niwei
	 * @since 2016年11月17日
	 * @version 1.0.0
	 * @param key
	 * @param value
	 * @param time
	 */
	public void set(final String key,final T value,final long time) {
		
		redisTemplate.execute(new RedisCallback<Boolean>() {

			@Override
			public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
				RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
				byte[] rkey = serializer.serialize(key);
				connection.expire(rkey, time);  //设置过期时间
				return connection.setNX(rkey, serializer.serialize(JSON.toJSONString(value, SerializerFeature.WriteClassName)));
			}
		});
	}
	
	
	/**
	 * 向redis存入数据，不设置过期时间。
	 * @author niwei
	 * @since 2016年11月17日
	 * @version 1.0.0
	 * @param key
	 * @param value
	 * @param time
	 */
	public void setNoTime(final String key,final T value) {
		
		redisTemplate.execute(new RedisCallback<Boolean>() {

			@Override
			public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
				RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
				byte[] rkey = serializer.serialize(key);
//				connection.expire(rkey, time);  //设置过期时间
				return connection.setNX(rkey, serializer.serialize(JSON.toJSONString(value, SerializerFeature.WriteClassName)));
			}
		});
	}
	
	/**
	 * 存储集合类型的value
	 * @author niwei
	 * @since 2016年11月17日
	 * @version 1.0.0
	 * @param key
	 * @param values
	 * @param time
	 */
	public void set(final String key, final Collection<T> values, final long time) {
		
		redisTemplate.execute(new RedisCallback<Boolean>() {

			@Override
			public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
				RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
				byte[] rkey = serializer.serialize(key);
				connection.expire(rkey, time);  //设置过期时间
				return connection.setNX(rkey, serializer.serialize(JSON.toJSONString(values, SerializerFeature.WriteClassName)));
			}
			
		});
	}
	
	/**
	 * See {@link MemoryCache#set(String, Object, long)} for detail.
	 */
	public void set(String key, T value) {
		set(key, value, 15*60);  //默认是15分钟
	}
	
	/**
	 * See {@link MemoryCache#set(String, Collection, long)} for detail.
	 */
	public void set(String key, Collection<T> values) {
		set(key, values, 15*60);  //默认是15分钟
	}
	
	/**
	 * 获取value
	 * @author niwei
	 * @since 2016年11月17日
	 * @version 1.0.0
	 * @param key
	 * @return
	 */
	public T get(final String key) {
		
		return redisTemplate.execute(new RedisCallback<T>() {

			@Override
			public T doInRedis(RedisConnection connection) throws DataAccessException {
				RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
				byte[] value = connection.get(serializer.serialize(key));
				T obj = null;
				if (value != null) {
					obj = JSON.parseObject(serializer.deserialize(value), new TypeReference<T>(){});
					//obj = DataResolver.toObject(serializer.deserialize(value), new TypeReference<T>(){});
				}
				return obj;
			}
		});
	}
	
	/**
	 * Compare with {@link MemoryCache#get(String)}.
	 */
	public Collection<T> getC(final String key) {
		
		return redisTemplate.execute(new RedisCallback<Collection<T>>() {

			@Override
			public Collection<T> doInRedis(RedisConnection connection) throws DataAccessException {
				RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
				byte[] values = connection.get(serializer.serialize(key));
				Collection<T> result = null;
				if (values != null) {
					result = JSON.parseObject(serializer.deserialize(values), new TypeReference<Collection<T>>(){});
					//result = DataResolver.toObject(serializer.deserialize(values), new TypeReference<List<T>>(){});
				}
				return result;
			}
		});
	}
	
	public void delete(String key) {
		redisTemplate.delete(key);
	}
	
	/**
	 * 批量删除。
	 * @author niwei
	 * @since 2016年11月17日
	 * @version 1.0.0
	 * @param keys
	 */
	public void delete(Collection<String> keys) {
		redisTemplate.delete(keys);
	}
}
